#1. 添加cmake版本说明
cmake_minimum_required(VERSION 3.1.3)
#2. 声明工程名称
project(friend_server)

set(target "friend_server")

set(CMAKE_CXX_FLAGS, "${CMAKE_CXX_FLAGS} -g")      #添加调试选项

#3. 检查并生成proto框架代码
#3.1 添加所需的proto映射代码文件名称
set(proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../proto)    #定义proto_path，存储proto映射文件的路径
set(proto_files user.proto base.proto friend.proto message.proto)
set(proto_hh "")
set(proto_cc "")
set(proto_srcs "") #proto的所有源码文件
foreach(proto_file ${proto_files})
    #3.2 检测框架代码文件是否已经生成
    #在哪里执行proto编译命令就哪里生成执行proto编译命令后的临时文件
    # user.proto 文件经过proto编译后生成 user.pb.h user.pb.cc 等文件
    #proto文件的名称肯定是动态变化的，需要我们进行字符串的处理，提取对应的proto映射文件名称
    string(REPLACE ".proto" ".pb.h" proto_hh ${proto_file})
    string(REPLACE ".proto" ".pb.cc" proto_cc ${proto_file})
    if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc})
        #3.3 如果没有生成，则预定义生成指令---用于在构建项目之间先生成框架代码
        #要执行的外部指令
        add_custom_command(     
            PRE_BUILD
            COMMAND protoc   #要执行的命令
            ARGS --cpp_out=${CMAKE_CURRENT_BINARY_DIR} -I ${proto_path}  --experimental_allow_proto3_optional ${proto_path}/${proto_file} #执行命令所需的参数
            DEPENDS ${proto_path}/${proto_file}   #执行的命令所要依赖的文件
            OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc}  #输出的文件
            COMMENT "生成protobuf框架代码文件: " ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc}
        )
    endif()
    
    #3.4 将所有生成的框架源码文件名保存起来
    list(APPEND proto_srcs ${CMAKE_CURRENT_BINARY_DIR}/${proto_cc})

endforeach(proto_file proto_files)

#4. 检查并生成ODB框架代码
#4.1 添加所需的ODB映射代码文件名称
set(odb_path ${CMAKE_CURRENT_SOURCE_DIR}/../odb)    #定义odb_path，存储odb映射文件的路径
set(odb_files user.hxx friend_relation.hxx friend_apply.hxx chat_session.hxx chat_session_member.hxx)
set(odb_hxx "")
set(odb_cxx "")
set(odb_srcs "") #odb的所有源码文件
foreach(odb_file ${odb_files})
    #4.2 检测框架代码文件是否已经生成
    #在哪里执行odb编译命令就哪里生成执行odb编译命令后的临时文件
    # user.hxx odb映射文件经过odb编译后生成 user-odb.hxx user-odb.cxx user-odb.ixx user.sql 等文件
    #odb映射文件的名称肯定是动态变化的，需要我们进行字符串的处理，提取对应的odb映射文件名称
    string(REPLACE ".hxx" "-odb.hxx" odb_hxx ${odb_file})
    string(REPLACE ".hxx" "-odb.cxx" odb_cxx ${odb_file})
    if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${odb_hxx})
        #4.3 如果没有生成，则预定义生成指令---用于在构建项目之间先生成框架代码
        #要执行的外部指令
        add_custom_command(     
            PRE_BUILD
            COMMAND odb   #要执行的命令
            ARGS -d mysql --generate-query --generate-schema --profile boost/date-time ${odb_path}/${odb_file}  #执行命令所需的参数
            DEPENDS ${odb_path}/${odb_file}   #执行的命令所要依赖的文件
            OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${odb_cxx}  #输出的文件
            COMMENT "生成ODB框架代码文件: " ${CMAKE_CURRENT_BINARY_DIR}/${odb_cxx}
        )
    endif()
    
    #4.4 将所有生成的框架源码文件名保存起来
    list(APPEND odb_srcs ${CMAKE_CURRENT_BINARY_DIR}/${odb_cxx})

endforeach(odb_file odb_files)

#5. 获取源码目录下的所有源码文件
set(src_files "")
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source src_files)

#6. 声明目标及依赖
add_executable(${target} ${src_files} ${proto_srcs} ${odb_srcs})


#7. 设置头文件默认搜索路径
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../odb)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../third/include)
include_directories(${CMAKE_CURRENT_BINARY_DIR})

#8. 设置需要链接的库
set(link_lib "-lgflags -lgtest -lspdlog -lfmt -lcpr -lelasticlient /usr/lib/x86_64-linux-gnu/libjsoncpp.so.19 -lbrpc -lssl -lcrypto -lprotobuf -lleveldb -letcd-cpp-api -lcpprest -lodb-mysql -lodb -lodb-boost -lcurl")   
target_link_libraries(${target} PUBLIC ${link_lib})

#测试客户端程序

set(test_src_users "")
set(test_target "friend_client")
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/test test_src_users)
add_executable(${test_target} ${test_src_users} ${proto_srcs})
target_link_libraries(${test_target} PUBLIC ${link_lib})


#9. 设置安装路径
INSTALL(TARGETS ${target} ${test_target} RUNTIME DESTINATION bin)
